package com.bright.hxj.cwduijie.service.impl;

import com.bright.hxj.cwduijie.converter.MonthlySettlementConverter;
import com.bright.hxj.cwduijie.enums.DataApi;
import com.bright.hxj.cwduijie.enums.SJJHBZ;
import com.bright.hxj.cwduijie.pojo.bo.ApiDataCollection;
import com.bright.hxj.cwduijie.pojo.dto.MonthlySettlementDto;
import com.bright.hxj.cwduijie.pojo.po.MonthlySettlement;
import com.bright.hxj.cwduijie.pojo.query.DuijieQuery;
import com.bright.hxj.cwduijie.pojo.vo.MonthlySettlementVO;
import com.bright.hxj.cwduijie.repository.MonthlySettlementRepository;
import com.bright.hxj.cwduijie.service.AbstractPerThousandApiService;
import com.bright.ghj.common.util.ListUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * @Author hxj
 * @Date 2024/7/29 14:40
 * @Description
 */

@Component
@RequiredArgsConstructor
@Slf4j
public class ApiMonthlySettlementServiceImpl extends AbstractPerThousandApiService<MonthlySettlementDto> {

    private final MonthlySettlementRepository repo;
    private final MonthlySettlementConverter converter;

    @Override
    public JpaSpecificationExecutor getJpaSpecificationExecutor() {
        return repo;
    }

    @Override
    public DataApi getDataApi() {
        return DataApi.MONTHLY_SETTLEMENT;
    }

    @Override
    public Function<MonthlySettlementDto, Integer> getIdFunc() {
        return MonthlySettlementDto::getId;
    }

//    @Override
//    public List<String> getNeedDuijieZtDataKeys() {
//        List<String> dataKeys = repo.getDistinctZtDataKeyBySjjhbz(SJJHBZ.WAITING.getValue());
//        dataKeys.addAll(repo.getDistinctZtDataKeyBySjjhbz(SJJHBZ.ERROR.getValue()));
//        return dataKeys;
//    }

    @Override
    protected void getData(ApiDataCollection apiDataCollection, DuijieQuery duijieQuery) {
        List<MonthlySettlement> monthlySettlements = new ArrayList<>();

        // 20240725 对接年月变成可以不指定了 为空时要处理 也要考虑只传年份不传月份的情况
        String selectedYearMonth = getSelectedYearMonth(duijieQuery);

//        List<MonthlySettlement> monthlySettlements = monthlySettlementRepository.getByZTDATAKEYAndYearMonth(duijieQuery.getZtDataKey(), yearMonth);
        // 20240722 根据sjjhbz=0或2去获取要推的月结数据
        if (selectedYearMonth == null) {
            // 如果未指定年月 则推所有需要对接的月结数据
            monthlySettlements.addAll(repo.getByZTDATAKEYAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.WAITING.getValue()));
            monthlySettlements.addAll(repo.getByZTDATAKEYAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.ERROR.getValue()));

            // 还要再加上所有改动过数据的年月 再显示调一次月结
            if (duijieQuery.getChangedYearMonths() != null) {
                for (String changedYearMonth : duijieQuery.getChangedYearMonths()) {
                    monthlySettlements.addAll(repo.getByZTDATAKEYAndYearMonth(duijieQuery.getZtDataKey(), changedYearMonth));
                }
            }
        } else {
            // 有指定年月 根据账套和年月获取当前推送的年月是否要月结的数据 不管sjjhbz
//            monthlySettlements.addAll(repo.getByZTDATAKEYAndYearMonth(duijieQuery.getZtDataKey(), selectedYearMonth));
            // v1.6.7（必指定年月） 如果有指定年月 先看sjjhbz是否为0 为0或2肯定推
            List<MonthlySettlement> months = repo.getByZTDATAKEYAndYearMonth(duijieQuery.getZtDataKey(), selectedYearMonth);
            List<MonthlySettlement> needDuijieMonths = ListUtil.toListByFilter(months, month -> month.getSjjhbz() == SJJHBZ.WAITING.getValue() || month.getSjjhbz() == SJJHBZ.ERROR.getValue());
            if (needDuijieMonths.size() > 0) {
                monthlySettlements.addAll(needDuijieMonths);
            } else {
                // 如果不是 则看是否改动过数据 有改动就推
                if (duijieQuery.getChangedYearMonths() != null && duijieQuery.getChangedYearMonths().contains(selectedYearMonth)) {
                    monthlySettlements.addAll(months);
                }
            }
        }

        Set<MonthlySettlement> monthlySettlementsSet = new HashSet<>(monthlySettlements);
        List<MonthlySettlementDto> monthlySettlementDtos = converter.poConvertDTO(new ArrayList<>(monthlySettlementsSet));
        apiDataCollection.setMonthlySettlements(monthlySettlementDtos);
    }

    // 新增取数方法 只根据传入的年月账套号获取数据
    public List<MonthlySettlementDto> getDataByDuijieQuery(DuijieQuery duijieQuery) {
        List<MonthlySettlement> monthlySettlements = new ArrayList<>();
        if (duijieQuery.getChangedYearMonths() != null) {
            for (String changedYearMonth : duijieQuery.getChangedYearMonths()) {
                monthlySettlements.addAll(repo.getByZTDATAKEYAndYearMonth(duijieQuery.getZtDataKey(), changedYearMonth));
            }
        }
        return converter.poConvertDTO(monthlySettlements);
    }

    // 设置该数据为待推送状态
    public void setDataToWaitingStatus(List<MonthlySettlementDto> monthlySettlementDtos) {
        List<MonthlySettlement> monthlySettlements = converter.dtoConvertPO(monthlySettlementDtos);
        for (MonthlySettlement monthlySettlement : monthlySettlements) {
            monthlySettlement.setSjjhbz(SJJHBZ.WAITING.getValue());
        }
        repo.saveAll(monthlySettlements);
    }

//    @Override
//    protected void checkDataValid(Map<String, CheckResultDto> checkResultDtoMap, ApiDataCollection apiDataCollection) {
//        super.checkDataValid(checkResultDtoMap, apiDataCollection);
//        // 若月结已推成功 拦住整套账不让推 (要按月份拦截 怎么按月份拦截？)
////        List<MonthlySettlementDto> monthlySettlements = apiDataCollection.getMonthlySettlements();
//
//    }

    @Override
    public void sendData(ApiDataCollection apiDataCollection, DuijieQuery duijieQuery, String batchId) throws JsonProcessingException {
        List<MonthlySettlementDto> monthlySettlementsDtos = apiDataCollection.getMonthlySettlements();
        List<MonthlySettlementVO> monthlySettlementVOS = converter.dtoConvertVO(monthlySettlementsDtos);

        sendListData(monthlySettlementVOS, ListUtil.toSingleList(monthlySettlementsDtos, getIdFunc()), batchId, duijieQuery.getAccSet());
    }

//    @Override
//    protected List<MonthlySettlementDto> getNeedDeleteData(DuijieQuery duijieQuery) {
//        return null;
//    }

    @Override
    public DataApi getDeleteDataApi() {
        return null;
    }

    @Override
    protected String getCheckDuplicateGroupByFields() {
        return "ZT_DATA_KEY, KJQJ";
    }

    @Override
    public Function<MonthlySettlementDto, String> getDataKeyFunc() {
        return null;
    }

    @Override
    public Function<ApiDataCollection, List<MonthlySettlementDto>> getDataFunc() {
        return ApiDataCollection::getMonthlySettlements;
    }

    @Override
    public String getYearMonthColumnName() {
        return "KJQJ";
    }
}
